import { ComponentInstance } from '@/types/visual-app'
import { Component, defineAsyncComponent } from 'vue'

// 组件类型定义
export interface ComponentConfig {
  id: string
  type: string
  name: string
  icon: string
  category: string
  description: string
  defaultWidth: number
  defaultHeight: number
  defaultData: any
  props: string[]
  component: Component
}


// 动态组件管理器
export class DynamicComponentManager {
  private static instance: DynamicComponentManager
  private componentRegistry: Map<string, ComponentConfig> = new Map()
  private componentCache: Map<string, Component> = new Map()

  private metaCache = new Map<string, any>();
  private asyncComponentCache = new Map<string, any>();

  private constructor() {
    this.initializeDefaultComponents()
  }

  // 单例模式
  public static getInstance(): DynamicComponentManager {
    if (!DynamicComponentManager.instance) {
      DynamicComponentManager.instance = new DynamicComponentManager()
    }
    return DynamicComponentManager.instance
  }

  // 初始化默认组件
  private initializeDefaultComponents() {
    // 柱状图
    this.registerComponent({
      id:'',
      type: 'bar',
      name: '柱状图',
      icon: 'el-icon-data-line',
      category: 'chart',
      description: '用于展示分类数据的柱状图',
      defaultWidth: 400,
      defaultHeight: 300,
      defaultData: {
        categories: ['一月', '二月', '三月', '四月'],
        series: [
          { name: 'A系列', data: [120, 200, 150, 80] },
          { name: 'B系列', data: [90, 160, 110, 60], color: '#67C23A' }
        ],
        showValue: false,
        valueFormat: 'number',
        precision: 2,
        showLegend: true
      },
      props: ['width', 'height', 'title', 'categories', 'series', 'showValue', 'valueFormat', 'precision', 'showLegend'],
      component: defineAsyncComponent(() => import('../widget/BarChart.vue'))
    })

    // 折线图
    this.registerComponent({
      id:'',
      type: 'line',
      name: '折线图',
      icon: 'el-icon-trend-charts',
      category: 'chart',
      description: '用于展示趋势数据的折线图',
      defaultWidth: 400,
      defaultHeight: 300,
      defaultData: {
        categories: ['一月', '二月', '三月', '四月'],
        series: [
          { name: '2023年', data: [120, 200, 150, 80], color: '#409EFF', smooth: true },
          { name: '2024年', data: [90, 160, 110, 60], color: '#67C23A', smooth: true }
        ],
        showValue: true,
        valueFormat: 'number',
        precision: 0,
        colors: ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
      },
      props: ['width', 'height', 'title', 'categories', 'series', 'showValue', 'valueFormat', 'precision', 'colors'],
      component: defineAsyncComponent(() => import('../widget/LineChart.vue'))
    })

    // 饼图
    this.registerComponent({
      id:'',
      type: 'pie',
      name: '饼图',
      icon: 'el-icon-pie-chart',
      category: 'chart',
      description: '用于展示占比数据的饼图',
      defaultWidth: 300,
      defaultHeight: 300,
      defaultData: {
        data: [
          { name: '类型A', value: 335, color: '#409EFF' },
          { name: '类型B', value: 310, color: '#67C23A' },
          { name: '类型C', value: 234, color: '#E6A23C' }
        ]
      },
      props: ['width', 'height', 'title', 'data'],
      component: defineAsyncComponent(() => import('../widget/PieChart.vue'))
    })

    // 仪表盘
    this.registerComponent({
      id:'',
      type: 'gauge',
      name: '仪表盘',
      icon: 'el-icon-odometer',
      category: 'chart',
      description: '用于展示进度或指标的仪表盘',
      defaultWidth: 300,
      defaultHeight: 200,
      defaultData: {
        value: 65,
        min: 0,
        max: 100,
        color: '#409EFF'
      },
      props: ['width', 'height', 'title', 'value', 'min', 'max', 'color'],
      component: defineAsyncComponent(() => import('../widget/GaugeChart.vue'))
    })

    // 统计卡片
    this.registerComponent({
      id:'',
      type: 'stat',
      name: '统计卡片',
      icon: 'el-icon-s-data',
      category: 'data',
      description: '用于展示关键指标的统计卡片',
      defaultWidth: 200,
      defaultHeight: 120,
      defaultData: {
        value: 1234,
        prefix: '',
        suffix: '',
        precision: 2,
        trend: '↑ 12.5%',
        trendColor: '#67C23A'
      },
      props: ['width', 'height', 'title', 'value', 'prefix', 'suffix', 'precision', 'trend', 'trendColor'],
      component: defineAsyncComponent(() => import('../widget/StatCard.vue'))
    })

    // 数据表格
    this.registerComponent({
      id:'',
      type: 'table',
      name: '数据表格',
      icon: 'el-icon-s-grid',
      category: 'data',
      description: '用于展示结构化数据的表格',
      defaultWidth: 400,
      defaultHeight: 300,
      defaultData: {
        columns: [
          { prop: 'name', label: '名称' },
          { prop: 'status', label: '状态' },
          { prop: 'time', label: '时间' }
        ],
        data: [
          { name: '设备A', status: '正常', time: '24小时' },
          { name: '设备B', status: '警告', time: '18小时' }
        ]
      },
      props: ['width', 'height', 'title', 'columns', 'data'],
      component: defineAsyncComponent(() => import('../widget/DataTable.vue'))
    })

    // 进度环
    this.registerComponent({
      id:'',
      type: 'progress',
      name: '进度环',
      icon: 'el-icon-s-claim',
      category: 'data',
      description: '用于展示进度的环形进度条',
      defaultWidth: 200,
      defaultHeight: 200,
      defaultData: {
        percentage: 75,
        strokeWidth: 6,
        color: '#409EFF'
      },
      props: ['width', 'height', 'title', 'percentage', 'strokeWidth', 'color'],
      component: defineAsyncComponent(() => import('../widget/ProgressRing.vue'))
    })
    // 图片组件
    this.registerComponent({
      id:'',
      type: 'image',
      name: '图片',
      icon: 'el-icon-picture',
      category: 'media',
      description: '用于展示图片的组件',
      defaultWidth: 120,
      defaultHeight: 120,
      defaultData: {
        src: '',
        alt: '',
        fit: 'contain',
        borderRadius: 0,
        bgColor: '#fff'
      },
      props: ['width', 'height', 'src', 'alt', 'fit', 'borderRadius', 'bgColor'],
      component: defineAsyncComponent(() => import('../widget/ImageWidget.vue'))
    })
    // UE流播放器组件
    this.registerComponent({
      id:'',
      type: 'ueplayer',
      name: 'UE流播放器',
      icon: 'el-icon-video-camera',
      category: 'media',
      description: '用于云渲染流播放的组件',
      defaultWidth: 800,
      defaultHeight: 600,
      defaultData: {
        cloudUrl: '',
        authorization: '',
        appid: ''
      },
      props: ['width', 'height', 'cloudUrl', 'authorization', 'appid'],
      component: defineAsyncComponent(() => import('../widget/UEPlayer.vue'))
    })
  }

  // 注册组件
  public registerComponent(config: ComponentConfig): void {
    this.componentRegistry.set(config.type, config)
  }

  // 获取组件配置
  public getComponentConfig(type: string): ComponentConfig | undefined {
    return this.componentRegistry.get(type)
  }

  // 获取组件实例
  public async getComponent(type: string): Promise<Component | null> {
    const config = this.getComponentConfig(type)
    if (!config) return null

    // 检查缓存
    if (this.componentCache.has(type)) {
      return this.componentCache.get(type)!
    }

    try {
      // 动态加载组件
      const component = await config.component
      this.componentCache.set(type, component)
      return component
    } catch (error) {
      console.error(`Failed to load component: ${type}`, error)
      return null
    }
  }

  /**
   * 获取组件元数据，自动缓存
   * @param componentId 组件唯一ID
   * @param fetchMeta 获取元数据的异步函数
   */
  public async getComponentMeta(componentId: string, fetchMeta: () => Promise<any>) {
    if (this.metaCache.has(componentId)) {
      return this.metaCache.get(componentId);
    }
    const meta = await fetchMeta();
    this.metaCache.set(componentId, meta);
    return meta;
  }

  /**
   * 获取异步组件，自动缓存
   * @param importPath 组件相对路径
   */
  public getAsyncComponent(importPath: string) {
    if (this.asyncComponentCache.has(importPath)) {
      return this.asyncComponentCache.get(importPath);
    }
    const comp = defineAsyncComponent(() => import(/* @vite-ignore */ importPath));
    this.asyncComponentCache.set(importPath, comp);
    return comp;
  }

  /**
   * 清空所有缓存
   */
  public clearCache() {
    this.metaCache.clear();
    this.asyncComponentCache.clear();
  }

  // 获取所有组件配置
  public getAllComponents(): ComponentConfig[] {
    return Array.from(this.componentRegistry.values())
  }

  // 按分类获取组件
  public getComponentsByCategory(category: string): ComponentConfig[] {
    return this.getAllComponents().filter(comp => comp.category === category)
  }


  // 获取组件属性
  public getComponentProps(instance: ComponentInstance): any {
    return {}
  }

  // 验证组件类型
  public isValidComponentType(type: string): boolean {
    return this.componentRegistry.has(type)
  }

  // 获取组件分类
  public getCategories(): string[] {
    const categories = new Set(this.getAllComponents().map(comp => comp.category))
    return Array.from(categories)
  }

  // 预加载组件
  public async preloadComponents(types: string[]): Promise<void> {
    const promises = types.map(type => this.getComponent(type))
    await Promise.all(promises)
  }

  /**
   * 通过组件路径动态加载组件
   * @param path 组件相对路径，如 '../widget/BarChart.vue'
   * @returns defineAsyncComponent 包裹的 Vue 组件
   */
  public static loadComponentByPath(path: string): Component {
    // 这里直接返回 defineAsyncComponent
    return defineAsyncComponent(() => import(/* @vite-ignore */ path))
  }

  public static loadComponentByData(componentData: ComponentInstance): Component {
    console.log('componentData-path=', componentData);
    return defineAsyncComponent(() => import(/* @vite-ignore */ componentData?.path))
  }

}

// 导出单例实例
export const componentManager = DynamicComponentManager.getInstance()

// 工具函数
// export const createComponentInstance = (type: string, x: number, y: number) => 
//   componentManager.createComponentInstance(type, x, y)

export const getComponentProps = (instance: ComponentInstance) => 
  componentManager.getComponentProps(instance)

export const getComponentsByCategory = (category: string) => 
  componentManager.getComponentsByCategory(category)

export const isValidComponentType = (type: string) => 
  componentManager.isValidComponentType(type)
